package com.example.syntax;

import org.junit.Test;

/*
 * Lambda对接口的要求
 *  虽然使用Lambda表达式可以对某些接口进行简单实现，不是所有的接口都可以使用Lambda表达式来实现。
 *  Lambda规定接口中只能有一个必须需要被实现的方法，不是规定接口中只能有一个方法
 *  注意：Java8中有另一个新特性：default，被default修饰的方法会有默认实现，不是必须被实现的方法，所以不影响Lambda表达式的使用。
 *
 * @FunctionalInterface
 *  专门来修饰函数式接口的，要求接口中的抽象方法只有一个。这个注解一般会和Lambda表达式一起使用。
 *
 * Lambda基础语法
 *  语法形式为 ()->{}，其中()用来描述参数列表，{}用来描述方法体，->为Lambda运算符，读作（goes to）。
 *
 * 函数式接口的6种表现形式
 *  NoReturnNoParam、NoReturnOneParam、NoReturnMultiParam
 *  ReturnNoParam、ReturnOneParam、ReturnMultiParam
 */
public class Demo {
    //最传统的接口使用方式
    @Test
    public void test1() {
        Impler impler = new Impler();
        impler.method();
    }

    //比较传统的对接口使用方式，匿名内部类
    @Test
    public void test2() {
        NoReturnNoParam intf = new NoReturnNoParam() {
            @Override
            public void method() {
                System.out.println("没有参数也没有返回值，匿名内部类");
            }
        };
        intf.method();
    }

    @Test
    public void test3_1() {
        NoReturnNoParam intf = () -> {
            System.out.println("没有参数也没有返回值，Lambda");
        };
        intf.method();
    }

    @Test
    public void test3_2() {
        NoReturnOneParam noReturnOneParam = (int a) -> {
            System.out.println("NoReturnOneParam param " + a);
        };
        noReturnOneParam.method(666);
    }

    @Test
    public void test3_3() {
        NoReturnMultiParam noReturnMultiParam = (int a, int b) -> {
            System.out.println("NoReturnOneParam param " + a + ":" + b);
        };
        noReturnMultiParam.method(666, 888);
    }

    @Test
    public void test4_1() {
        ReturnNoParam returnNoParam = () -> {
            return 999;
        };
        System.out.println("ReturnNoParam return " + returnNoParam.method());
    }

    //参数列表只有一个时，()可以省略
    //Lambda体只有一行代码时，{}可以省略，return也要省略
    @Test
    public void test4_2() {
        ReturnOneParam returnOneParam = a -> a + 1;
        System.out.println("ReturnOneParam return " + returnOneParam.method(5));
    }

    //参数类型可以省略，但是必须所有参数都不写类型
    @Test
    public void test4_3() {
        ReturnMultiParam returnMultiParam = (a, b) -> a + b;
        System.out.println("ReturnMultiParam return " + returnMultiParam.method(5, 5));
    }
}


class Impler implements NoReturnNoParam {

    @Override
    public void method() {
        System.out.println("没有参数也没有返回值，接口实现");
    }
}